package cn.lg.soar.database.util;

import cn.lg.soar.common.util.data.DataUtil;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @author luguoxiang 469599794@qq.com
 * @Date: 2024/4/1 12:08
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class SqlHandler {

    private final Function<Integer, String> placeholder;

    public SqlHandler(Function<Integer, String> placeholder) {
        this.placeholder = placeholder;
    }

    public static String toLikeStr(String value) {
        return "%" + value + "%";
    }

    /**
     * 获取in占位符
     * @param values
     * @return
     */
    public String getInPlaceholder(int length) {
        String[] res = new String[length];
        for (int i = 0; i < length; i++) {
            res[i] = placeholder.apply(i);
        }
        return "IN(" + String.join(",", res) + ")";
    }

    /**
     * 获取in占位符
     * @param values
     * @return
     */
    public String getInPlaceholder(Collection<?> values) {
        return getInPlaceholder(values.size());
    }

    /**
     * 获取in占位符
     * @param values
     * @return
     */
    public <T>String getInPlaceholder(T[] values) {
        return getInPlaceholder(values.length);
    }

    public void handleLikeStr(String value, BiConsumer<String, String> consumer) {
        if (DataUtil.isValuable(value)) {
            consumer.accept(" LIKE " + placeholder.apply(0), toLikeStr(value));
        }
    }

    public void handleInOrEq(Collection<?> values, BiConsumer<String, Object[]> consumer) {
        if (DataUtil.isValuable(values)) {
            handleInOrEq(values.toArray(), consumer);
        }
    }

    public void handleInOrEq(Object[] values, BiConsumer<String, Object[]> consumer) {
        if (DataUtil.isValuable(values)) {
            consumer.accept(
                    values.length == 1 ? "=" + placeholder.apply(0) : getInPlaceholder(values),
                    values
            );
        }
    }

    /**
     * 处理范围查询
     * @param start
     * @param end
     * @param consumer
     */
    public void handleRange(Object start, Object end, BiConsumer<String, Object[]> consumer) {
        boolean startFlag = DataUtil.isValuable(start);
        boolean endFlag = DataUtil.isValuable(end);
        if (startFlag || endFlag) {
            if (startFlag && endFlag) {
                consumer.accept("BETWEEN " + placeholder.apply(0) + " AND " + placeholder.apply(1), new Object[]{ start, end });
            } else if (startFlag) {
                consumer.accept(">=" + placeholder.apply(0), new Object[]{ start });
            } else {
                consumer.accept("<=" + placeholder.apply(0), new Object[]{ end });
            }
        }
    }
}
